package com.topisv.tms.rest.qimen.qmservice;

import java.io.StringReader;
import java.io.StringWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.bind.JAXB;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.LogosticsInfo;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillBoxPre;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillItemPre;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillPre;
import com.topisv.tms.exception.ErrorCode;
import com.topisv.tms.exception.PaiUException;
import com.topisv.tms.exception.QMErrorCode;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.rest.qimen.qmentity.ReceiverInfo;
import com.topisv.tms.rest.qimen.qmentity.SenderInfo;
import com.topisv.tms.rest.qimen.qmentity.request.instoragebillcreate.InstorageBill;
import com.topisv.tms.rest.qimen.qmentity.request.instoragebillcreate.InstorageBillCreate;
import com.topisv.tms.rest.qimen.qmentity.request.instoragebillcreate.InstorageBillItem;
import com.topisv.tms.rest.qimen.qmentity.response.QMReponse;
import com.topisv.tms.rest.qimen.qmentity.response.ResponseFlagType;
import com.topisv.tms.rest.qimen.qmentity.response.instoragebillcreate.InstorageBillCreateResult;
import com.topisv.tms.rest.qimen.request.RequestParams;
import com.topisv.tms.rest.qimen.response.ResponseParams;
import com.topisv.tms.rest.qimen.util.validator.ValidatorUtil;
import com.topisv.tms.utils.vo.PreInstorageVo;
import com.topisv.tms.service.LogosticsInfoService;
import com.topisv.tms.service.stock.preinstorage.PreInstorageService;

@Component
@Transactional(readOnly = true)
public class InstorageBillCreateService {
    
    private static final Logger logger = LoggerFactory.getLogger(InstorageBillCreateService.class);
    
    @Autowired
    private EdiGoodsSkuDao ediGoodsSkuDao;
    
    @Autowired
    private LogosticsInfoService logosticsInfoService;
    
    @Autowired
    private PreInstorageService preInstorageService;
    
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public ResponseParams execute(RequestParams params)
        throws PaiUException
    {
        // 返回请求参数
        ResponseParams response = new ResponseParams();
        InstorageBillCreateResult result = new InstorageBillCreateResult();
        String customerCode = "";// 货主编码
        String customerOrderNo = "";// 来源订单号
        try {
            logger.info("新增入库");
            String stringXml = params.getRequestXml();
            
            InstorageBillCreate instoragebillcreate = JAXB.unmarshal(new StringReader(stringXml), InstorageBillCreate.class);
            
            // 报文校验
            String reqValidatorMsg = ValidatorUtil.qmXmlValidator(instoragebillcreate);
            if (!ValidatorUtil.SUCCESS_CODE.equals(reqValidatorMsg)) {
                response.setResponseXml(reqValidatorMsg.toString());
                return response;
            }
            
            InstorageBill instorage = instoragebillcreate.getEntryOrder();
            SenderInfo senderInfo = instorage.getSenderInfo();
            ReceiverInfo receiverInfo = instorage.getReceiverInfo();
            
            // set预约单信息
            InstorageBillPre pre = new InstorageBillPre();
            pre.setOrderStatus("1"); // 改成已发货状态
            pre.setCustomerOrderNo(instorage.getEntryOrderCode());
            customerOrderNo = instorage.getEntryOrderCode();
            // pre.setCustomerCode(instorage.getOwnerCode());
            pre.setInwarehouseCode(instorage.getWarehouseCode());
            pre.setOrderCreateTime(instorage.getOrderCreateTime());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isNotEmpty(instorage.getExpectStartTime())) {
                pre.setPreSendTm(sdf.parse(instorage.getExpectStartTime().toString()));
            }
            pre.setExpectEndTime(instorage.getExpectEndTime());
            pre.setExpressNo(instorage.getExpressCode());
            pre.setLogisticsCode(instorage.getLogisticsCode());
            pre.setLogisticsName(instorage.getLogisticsName());
            pre.setRemark(instorage.getRemark());
            /**
             * 设置预约入库单类型 caomingwu 0000265
             */
            pre.setBillType(instorage.getOrderType());
            
            // set发/收的信息
            LogosticsInfo logosticsInfo = new LogosticsInfo();
            logosticsInfo.setExpressNo(instorage.getExpressCode());
            logosticsInfo.setLogosticsInfo(instorage.getLogisticsCode());
            
            if (senderInfo != null) {
                logosticsInfo.setSenderCompany(senderInfo.getCompany());
                logosticsInfo.setSenderZipCode(senderInfo.getZipCode());
                logosticsInfo.setSenderProvince(senderInfo.getProvince());
                logosticsInfo.setSenderCity(senderInfo.getCity());
                logosticsInfo.setSenderArea(senderInfo.getArea());
                logosticsInfo.setSenderTown(senderInfo.getTown());
                logosticsInfo.setSenderDetailAddress(senderInfo.getDetailAddress());
                logosticsInfo.setSenderName(senderInfo.getName());
                logosticsInfo.setSenderMobile(senderInfo.getMobile());
                logosticsInfo.setSenderTel(senderInfo.getTel());
                logosticsInfo.setSenderEmail(senderInfo.getEmail());
                logosticsInfo.setSenderCountryCode(senderInfo.getCountryCode());
            }
            if (receiverInfo != null) {
                logosticsInfo.setReceiverCompany(receiverInfo.getCompany());
                logosticsInfo.setReceiverZipCode(receiverInfo.getZipCode());
                logosticsInfo.setReceiverProvince(receiverInfo.getProvince());
                logosticsInfo.setReceiverCity(receiverInfo.getCity());
                logosticsInfo.setReceiverArea(receiverInfo.getArea());
                logosticsInfo.setReceiverTown(receiverInfo.getTown());
                logosticsInfo.setReceiverDetailAddress(receiverInfo.getDetailAddress());
                logosticsInfo.setReceiverName(receiverInfo.getName());
                logosticsInfo.setReceiverMobile(receiverInfo.getMobile());
                logosticsInfo.setReceiverTel(receiverInfo.getTel());
                logosticsInfo.setReceiverEmail(receiverInfo.getEmail());
                logosticsInfo.setReceiverCountryCode(receiverInfo.getCountryCode());
            }
            List<InstorageBillBoxPre> boxes = new ArrayList<InstorageBillBoxPre>();
            InstorageBillBoxPre box = new InstorageBillBoxPre();
            box.setBoxCode("QMBOX0001");
            boxes.add(box);
            // 设置预约单详情信息
            List<InstorageBillItemPre> itemPres = new ArrayList<InstorageBillItemPre>();
            for (InstorageBillItem item : instoragebillcreate.getPreItem()) {
                EdiGoodsSku goodsSku = ediGoodsSkuDao.findOne(Long.parseLong(item.getItemId()));
                if (goodsSku == null) {
                    throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] {item.getItemCode()});
                }
                
                if (goodsSku.getIsBatchMgmt().equals("1") && (item.getBatchCode() == null || item.getBatchCode().equals(""))){
                    throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] {item.getItemCode() + "必须输入批次"});
                }
                
                if(goodsSku.getIsShelfLifeMgmt().equals("1")){
                    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
                    if(goodsSku.getShelfLife() == null || goodsSku.getShelfLife().equals(0)){
                        if((item.getProductDate() == null || item.getProductDate().equals("")) || 
                            (item.getExpireDate() == null || item.getExpireDate().equals(""))){
                            throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] {item.getItemCode() + "未维护保质期，必须输入生产日期及过期日期"});
                        }else{
                            //验证生产日期和过期日期的日期格式
                            Date date = sdf2.parse(item.getProductDate());
                            date = sdf2.parse(item.getExpireDate());
                            if(date.before(new Date())){
                                throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] {item.getItemCode() + "过期日期小于当天"}); 
                            }
                        }
                    }else{
                        if((item.getProductDate() == null || item.getProductDate().equals("")) && 
                            (item.getExpireDate() == null || item.getExpireDate().equals(""))){
                            throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] {item.getItemCode() + "必须输入生产日期或过期日期"});
                        }else{
                            if(item.getExpireDate() == null || item.getExpireDate().equals("")){
                                Date date = sdf2.parse(item.getProductDate());
                                date = new Date(date.getTime() + (goodsSku.getShelfLife() * 60 * 60 * 1000));
                                if(date.before(new Date())){
                                    throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] {item.getItemCode() + "过期日期小于当天"}); 
                                }
                                item.setExpireDate(sdf2.format(date));
                            }else{
                                Date date = sdf2.parse(item.getExpireDate());
                                if(date.before(new Date())){
                                    throw new PaiUException(ErrorCode.SKU_CONFIG_ERROR, new String[] {item.getItemCode() + "过期日期小于当天"}); 
                                }
                                date = new Date(date.getTime() - (goodsSku.getShelfLife() * 60 * 60 * 1000));
                                item.setProductDate(sdf2.format(date));
                            }
                        }
                    }
                }
                
                
                pre.setCustomerCode(item.getOwnerCode());
                customerCode = item.getOwnerCode();
                
                InstorageBillItemPre itemPre = new InstorageBillItemPre();
                itemPre.setLineNo(item.getOrderLineNo());
                itemPre.setSkuCode(goodsSku.getSku());
                itemPre.setItemId(goodsSku.getId().toString());
                itemPre.setGoodsNum(item.getQuantity());
                itemPre.setBoxCode("QMBOX0001");
                itemPre.setInventoryType(item.getInventoryType());
                itemPre.setProductDate(item.getProductDate());
                itemPre.setExpireDate(item.getExpireDate());
                itemPre.setProduceCode(item.getProduceCode());
                itemPre.setBatchCode(item.getBatchCode());
                itemPres.add(itemPre);
            }
            
            PreInstorageVo preInstorageVo = new PreInstorageVo();
            preInstorageVo.setInstorageBillPre(pre);
            preInstorageVo.setInstorageBillBoxPres(boxes);
            preInstorageVo.setInstorageBillItemPres(itemPres);
            
            // 所有经奇门接口的入库单都认为是预约入库,否则无法与系统内的调拨入库区分 edit by yanlei 2016-03-07
            String billtype = "preOrder";
            /*
             * if("CGRK".equals(instorage.getOrderType())){
             * // billtype = "customer";
             * billtype = "preOrder";
             * }
             * else if("DBRK".equals(instorage.getOrderType())){
             * billtype = "allot";
             * }
             * else if("QTRK".equals(instorage.getOrderType())){
             * billtype = "other";
             * }
             */
            /**
             * 校验入库单重复 caomingwu
             * order_status预约入库单状态(0:已预约 1:已发货 2:已点收 3:取消)
             */
            InstorageBillPre inBillPre = preInstorageService.findByCustomerCodeAndCustomerOrderNo2(customerCode, customerOrderNo);
            if (null == inBillPre) {
                logosticsInfoService.saveLogosticsInfo(logosticsInfo);
                InstorageBillPre instorageBillPre = preInstorageService.saveInstorageBillPre(preInstorageVo, billtype);
                logger.info("入库成功");
                result.setFlag("success");
                result.setCode(QMErrorCode.SUCCESS.getCode());
                result.setMessage(QMErrorCode.SUCCESS.getMessage());
                result.setEntryOrderId(instorageBillPre.getBillCode().toString());
            } else {
                logger.info("入库单创建失败，入库单已存在：customerCode=" + customerCode + ";customerOrderNo=" + customerOrderNo);
                result.setFlag("failure");
                result.setCode("");
                result.setMessage("入库单创建失败，入库单已存在：customerCode=" + customerCode + ";customerOrderNo=" + customerOrderNo);
                result.setEntryOrderId("");
            }
        } catch (ParseException e) {
            logger.error("保存错误", e);
            result.setFlag("failure");
            result.setCode("");
            result.setMessage("没有对应的SKU:" + e.getMessage());
            result.setEntryOrderId("");
        } catch(PaiUException e){
            logger.error("保存错误", e);
            result.setFlag("failure");
            result.setCode("");
            result.setMessage(e.getMessage());
        } catch (Exception e) {
            logger.error("保存错误", e);
            result.setFlag("failure");
            result.setCode("");
            result.setMessage("失败：" + e.getMessage());
            result.setEntryOrderId("");
        }
        StringWriter writer = new StringWriter();
        JAXB.marshal(result, writer);
        response.setResponseXml(writer.toString());
        return response;
    }
}
